package com.africanmoviesmobile.ui;

import java.io.IOException;
import java.text.NumberFormat;

import org.pixmob.httpclient.HttpClientException;

import android.annotation.SuppressLint;
import android.app.AlertDialog;
import android.app.Dialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.os.Bundle;
import android.support.v4.app.DialogFragment;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.RatingBar;
import android.widget.RatingBar.OnRatingBarChangeListener;
import android.widget.TextView;

import com.africanmoviesmobile.R;
import com.africanmoviesmobile.util.bitmap.ImageCache.ImageCacheParams;
import com.africanmoviesmobile.util.bitmap.ImageFetcher;
import com.africanmoviesmobile.webservice.AmmWebService;
import com.africanmoviesmobile.webservice.BasicAsyncCallback;
import com.africanmoviesmobile.webservice.WebServiceException;
import com.africanmoviesmobile.webservice.inf.Cast;
import com.africanmoviesmobile.webservice.inf.Crew;
import com.africanmoviesmobile.webservice.inf.Movie;
import com.africanmoviesmobile.webservice.inf.User;
import com.africanmoviesmobile.webservice.inf.WebserviceObject;

public class MovieDetailActivity extends BaseActivity implements OnClickListener {

	public static final String EXTRA_MOVIE_ID = "movie_id";
	
	private LayoutInflater mLayoutInflater;
	private LinearLayout mWishlistControlWrapper;
	private LinearLayout mPlaylistControlWrapper;
	private LinearLayout mPlayControlWrapper;
	
	private TextView mPreviewControl;
	private TextView mPlayControl;
	private TextView mWishlistControl;
	private TextView mPlaylistControl;
	private ImageView mRatings;
	private TextView mRatingsCount;
	private ImageView mYourRating;
	private TextView mRateThisMovie; 
	
	private ImageFetcher mMovieCoverDetailImageFetcher;
	private ImageFetcher mThumbnailImageFetcher;
	
	AmmWebService mAmmWebService;
	private Movie mMovieInfo = null;
	private User mUserInfo = null;
	
	int[] mRatingsStarOrangeArray;
	int mUserRating = 0;
	
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
	
		setContentView(R.layout.movie_detail_activity);
		
		mLayoutInflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);

		int movieCoverDetailWidth = getResources().getDimensionPixelSize(R.dimen.movie_cover_detail_width);
		int movieCoverDetailHeight = getResources().getDimensionPixelSize(R.dimen.movie_cover_detail_height);
		mMovieCoverDetailImageFetcher = new ImageFetcher(this, movieCoverDetailWidth, movieCoverDetailHeight);
		mMovieCoverDetailImageFetcher.setLoadingImage(R.drawable.empty_photo);
		mMovieCoverDetailImageFetcher.addImageCache(getSupportFragmentManager(), new ImageCacheParams(this, CACHE_DIR_FULL));
		
		int thumbnailWidth = getResources().getDimensionPixelSize(R.dimen.thumbnail_width);
		int thumbnailHeight = getResources().getDimensionPixelSize(R.dimen.thumbnail_height);
		mThumbnailImageFetcher = new ImageFetcher(this, thumbnailWidth, thumbnailHeight);
		mThumbnailImageFetcher.setLoadingImage(R.drawable.empty_photo);
		mThumbnailImageFetcher.addImageCache(getSupportFragmentManager(), new ImageCacheParams(this, CACHE_DIR_THUMBNAIL));
		
		mPreviewControl = (TextView) findViewById(R.id.preview_control);
		mPreviewControl.setOnClickListener(this);
		
		mPlayControl = (TextView) findViewById(R.id.play_control);
		mPlayControl.setOnClickListener(this);
		
		mWishlistControl = (TextView) findViewById(R.id.wishlist_control);
		mWishlistControl.setOnClickListener(this);
		
		mPlaylistControl = (TextView) findViewById(R.id.playlist_control);
		mPlaylistControl.setOnClickListener(this);
		
		mWishlistControlWrapper = (LinearLayout) findViewById(R.id.wishlist_control_wrapper);
		mPlaylistControlWrapper = (LinearLayout) findViewById(R.id.playlist_control_wrapper);
		mPlayControlWrapper = (LinearLayout) findViewById(R.id.play_control_wrapper);
		
		mRatings = (ImageView) findViewById(R.id.ratings);
		mRatingsCount = (TextView) findViewById(R.id.ratings_count);
		mYourRating = (ImageView) findViewById(R.id.your_rating);
		mRateThisMovie = (TextView) findViewById(R.id.rate_movie);
		mRateThisMovie.setOnClickListener(this);
		
		mRatingsStarOrangeArray = new int[]{
	    		R.drawable.rating_orange_0_star,
	    		R.drawable.rating_orange_1_star,
	    		R.drawable.rating_orange_2_star,
	    		R.drawable.rating_orange_3_star,
	    		R.drawable.rating_orange_4_star,
	    		R.drawable.rating_orange_5_star
	    };
		
		final LinearLayout castWrapper = (LinearLayout) findViewById(R.id.cast_wrapper);
		final LinearLayout writersWrapper = (LinearLayout) findViewById(R.id.writers_wrapper);
		final LinearLayout producersWrapper = (LinearLayout) findViewById(R.id.producers_wrapper);
		final LinearLayout directorsWrapper = (LinearLayout) findViewById(R.id.directors_wrapper);
		
		mAmmWebService = AmmWebService.getInstance(this);
		
		final int movieId = getIntent().getIntExtra(EXTRA_MOVIE_ID, 0);
		
		mAmmWebService.getMovie(movieId, new BasicAsyncCallback() {

			public void onComplete(final WebserviceObject[] result, final Object state) {
				
				Movie movieInfo = (Movie) result[0];
				
				if ((movieInfo != null)) {

					mMovieInfo = movieInfo;
					
					Cast[] cast = (Cast[]) mMovieInfo.getFullCast();
					Crew[] writers = (Crew[]) mMovieInfo.getWriters();
					Crew[] producers = (Crew[]) mMovieInfo.getProducers();
					Crew[] directors = (Crew[]) mMovieInfo.getDirectors();
					
					
					
					try {
						mUserInfo = (User) mAmmWebService.getUser(getLoginEmail());
					} catch (HttpClientException e) {
						Log.w("AMM HttpClientException:", e.getMessage());
					} catch (IOException e) {
						Log.w("AMM IOException:", e.getMessage());
					} catch (WebServiceException e) {
						Log.w("AMM WebServiceException:", e.getMessage());
						toastMessage(R.string.user_info_error);
					}
					
					boolean inWishlist = false;
					boolean inPlaylist = false;
					
					if(mUserInfo != null){
						
						try {
							
							inWishlist = mUserInfo.movieInWishlist(movieId);
							
						} catch (HttpClientException e) {
							Log.w("AMM HttpClientException:", e.getMessage());
						} catch (IOException e) {
							Log.w("AMM IOException:", e.getMessage());
						} catch (WebServiceException e) {
							Log.w("AMM WebServiceException:", e.getMessage());
							toastMessage(e.getMessage());
						}
						
						try {
							
							inPlaylist = mUserInfo.movieInPlaylist(movieId);
							
						} catch (HttpClientException e) {
							Log.w("AMM HttpClientException:", e.getMessage());
						} catch (IOException e) {
							Log.w("AMM IOException:", e.getMessage());
						} catch (WebServiceException e) {
							Log.w("AMM WebServiceException:", e.getMessage());
							toastMessage(e.getMessage());
						}
						
					}
					
					
					try {
						
						mUserRating = mMovieInfo.getUserRating(getLoginEmail());
						
					} catch (HttpClientException e) {
						Log.w("AMM HttpClientException:", e.getMessage());
					} catch (IOException e) {
						Log.w("AMM IOException:", e.getMessage());
					} catch (WebServiceException e) {
						Log.w("AMM WebServiceException:", e.getMessage());
						toastMessage(e.getMessage());
					}
					
					runOnUiThread(new Runnable() {
						public void run() {
							
							ImageView movieCover = (ImageView) findViewById(R.id.movie_cover);
							TextView movieTitle = (TextView) findViewById(R.id.movie_title);
							TextView genres = (TextView) findViewById(R.id.genres);
							TextView runTime = (TextView) findViewById(R.id.run_time);
							TextView releaseDate = (TextView) findViewById(R.id.release_date);
							TextView mpaaRating = (TextView) findViewById(R.id.mpaa_rating);
							TextView synopsis = (TextView) findViewById(R.id.synopsis);
							TextView language = (TextView) findViewById(R.id.language);
							TextView country = (TextView) findViewById(R.id.country);
							
							mMovieCoverDetailImageFetcher.loadImage(mMovieInfo.getCover(), movieCover);
							
							movieTitle.setText(mMovieInfo.getTitle());
							genres.setText(mMovieInfo.getGenres());
							runTime.setText(mMovieInfo.getRunTime() + " Min");
							releaseDate.setText(mMovieInfo.getReleaseDate());
							mpaaRating.setText(mMovieInfo.getMpaaRating());
							synopsis.setText(mMovieInfo.getSynopsis());
							language.setText(mMovieInfo.getLanguage());
							country.setText(mMovieInfo.getCountry());
							
							mRatings.setImageResource(mRatingsStarOrangeArray[mMovieInfo.getRatings()]);
							mRatingsCount.setText(NumberFormat.getInstance().format(mMovieInfo.getRatingsCount()) + " " + getString(R.string.ratings));
							mYourRating.setImageResource(mRatingsStarOrangeArray[mUserRating]);
							
						}
					});
					
					if(inWishlist){
						runOnUiThread(new Runnable() {
							public void run() {
								mWishlistControlWrapper.setVisibility(View.GONE);
							}
						});
					}
					
					if(inPlaylist){
						runOnUiThread(new Runnable() {
							public void run() {
								mPlaylistControlWrapper.setVisibility(View.GONE);
								mPlayControlWrapper.setVisibility(View.VISIBLE);
							}
						});
					}
					
					if(cast != null){
						
						for (int i = 0; i < cast.length; i++) {
							
							final Cast castInfo = (Cast) cast[i];
							
							runOnUiThread(new Runnable() {public void run() { 
								
								View movieCastRow = mLayoutInflater.inflate(R.layout.movie_cast_crew_row, null, false);
				            	
				            	TextView celebName = (TextView) movieCastRow.findViewById(R.id.celeb_name);
				            	celebName.setText(castInfo.getName());
				            	
				            	TextView roleName = (TextView) movieCastRow.findViewById(R.id.role_name);
				            	roleName.setText(castInfo.getRoleName());
				            	
				            	ImageView celebDefaultPhoto = (ImageView) movieCastRow.findViewById(R.id.celeb_default_photo);
				            	mThumbnailImageFetcher.loadImage(castInfo.getDefaultPhoto(), celebDefaultPhoto);
				        		
				            	movieCastRow.setOnClickListener(new View.OnClickListener() {
									@Override
									public void onClick(View view) {
										final Intent intent = new Intent(MovieDetailActivity.this, CelebDetailActivity.class);
										intent.putExtra(CelebDetailActivity.EXTRA_CELEB_ID, (int) castInfo.getId());
								        startActivity(intent);
									}
								});
				            	
				            	castWrapper.addView(movieCastRow);
								
							}});
							
						}
					}
					
					if(writers != null){
						
						for (int i = 0; i < writers.length; i++) {
							
							final Crew writerInfo = (Crew) writers[i];
							
							runOnUiThread(new Runnable() {public void run() { 
								
								View movieCrewRow = mLayoutInflater.inflate(R.layout.movie_cast_crew_row, null, false);
				            	
				            	TextView celebName = (TextView) movieCrewRow.findViewById(R.id.celeb_name);
				            	celebName.setText(writerInfo.getName());
				            	
				            	TextView roleName = (TextView) movieCrewRow.findViewById(R.id.role_name);
				            	roleName.setText(writerInfo.getRoleName());
				            	
				            	ImageView celebDefaultPhoto = (ImageView) movieCrewRow.findViewById(R.id.celeb_default_photo);
				            	mThumbnailImageFetcher.loadImage(writerInfo.getDefaultPhoto(), celebDefaultPhoto);
				        		
				            	movieCrewRow.setOnClickListener(new View.OnClickListener() {
									@Override
									public void onClick(View view) {
										final Intent intent = new Intent(MovieDetailActivity.this, CelebDetailActivity.class);
										intent.putExtra(CelebDetailActivity.EXTRA_CELEB_ID, (int) writerInfo.getId());
								        startActivity(intent);
									}
								});
				            	
				            	writersWrapper.addView(movieCrewRow);
								
							}});
							
						}
					}
					
					if(producers != null){
						
						for (int i = 0; i < producers.length; i++) {
							
							final Crew producerInfo = (Crew) producers[i];
							
							runOnUiThread(new Runnable() {public void run() { 
								
								View movieCrewRow = mLayoutInflater.inflate(R.layout.movie_cast_crew_row, null, false);
				            	
				            	TextView celebName = (TextView) movieCrewRow.findViewById(R.id.celeb_name);
				            	celebName.setText(producerInfo.getName());
				            	
				            	TextView roleName = (TextView) movieCrewRow.findViewById(R.id.role_name);
				            	roleName.setText(producerInfo.getRoleName());
				            	
				            	ImageView celebDefaultPhoto = (ImageView) movieCrewRow.findViewById(R.id.celeb_default_photo);
				            	mThumbnailImageFetcher.loadImage(producerInfo.getDefaultPhoto(), celebDefaultPhoto);
				        		
				            	movieCrewRow.setOnClickListener(new View.OnClickListener() {
									@Override
									public void onClick(View view) {
										final Intent intent = new Intent(MovieDetailActivity.this, CelebDetailActivity.class);
										intent.putExtra(CelebDetailActivity.EXTRA_CELEB_ID, (int) producerInfo.getId());
								        startActivity(intent);
									}
								});
				            	
				            	producersWrapper.addView(movieCrewRow);
								
							}});
							
						}
					}
					
					if(directors != null){
						
						for (int i = 0; i < directors.length; i++) {
							
							final Crew directorInfo = (Crew) directors[i];
							
							runOnUiThread(new Runnable() {public void run() { 
								
								View movieCrewRow = mLayoutInflater.inflate(R.layout.movie_cast_crew_row, null, false);
				            	
				            	TextView celebName = (TextView) movieCrewRow.findViewById(R.id.celeb_name);
				            	celebName.setText(directorInfo.getName());
				            	
				            	TextView roleName = (TextView) movieCrewRow.findViewById(R.id.role_name);
				            	roleName.setText(directorInfo.getRoleName());
				            	
				            	ImageView celebDefaultPhoto = (ImageView) movieCrewRow.findViewById(R.id.celeb_default_photo);
				            	mThumbnailImageFetcher.loadImage(directorInfo.getDefaultPhoto(), celebDefaultPhoto);
				        		
				            	movieCrewRow.setOnClickListener(new View.OnClickListener() {
									@Override
									public void onClick(View view) {
										final Intent intent = new Intent(MovieDetailActivity.this, CelebDetailActivity.class);
										intent.putExtra(CelebDetailActivity.EXTRA_CELEB_ID, (int) directorInfo.getId());
								        startActivity(intent);
									}
								});
				            	
				            	directorsWrapper.addView(movieCrewRow);
								
							}});
							
						}
					}
					
					runOnUiThread(new Runnable() {
						public void run() {
							
							LinearLayout loadingProgress = (LinearLayout) findViewById(R.id.loading_progress);
							LinearLayout container = (LinearLayout) findViewById(R.id.container);
							
							loadingProgress.setVisibility(View.GONE);
							container.setVisibility(View.VISIBLE);
							
						}
					});
				}
				
			}

			public void onHttpClientException(final HttpClientException e, final Object state) {
				Log.w("AMM HttpClientException:", e.getMessage());
			}
			
			public void onIOException(final IOException e, final Object state) {
				Log.w("AMM IOException:", e.getMessage());
			}

			public void onWebServiceException(final WebServiceException e, final Object state) {
				Log.w("AMM WebServiceException:", e.getMessage());
				toastMessage(e.getMessage());
			}

		}, null);

		
	}
	
	@Override
    public void onResume() {
        super.onResume();

        mMovieCoverDetailImageFetcher.setExitTasksEarly(false);
                
        mThumbnailImageFetcher.setExitTasksEarly(false);
    }

    @Override
    public void onPause() {
        super.onPause();
        
        mMovieCoverDetailImageFetcher.setPauseWork(false);
        mMovieCoverDetailImageFetcher.setExitTasksEarly(true);
        mMovieCoverDetailImageFetcher.flushCache();
        
        mThumbnailImageFetcher.setPauseWork(false);
        mThumbnailImageFetcher.setExitTasksEarly(true);
        mThumbnailImageFetcher.flushCache();
    }

    @Override
    public void onDestroy() {
        super.onDestroy();

        mMovieCoverDetailImageFetcher.closeCache();
                
        mThumbnailImageFetcher.closeCache();
    }

    @Override
	public void onClick(View view) {

		switch (view.getId()) {
			case R.id.preview_control:
				playVideo(mMovieInfo.getPreviewCdnUrl());
				break;
			case R.id.play_control:
				playVideo(mMovieInfo.getCdnUrl());
				break;	
			case R.id.wishlist_control:
				
				if(mUserInfo != null){
					
					toastMessage(R.string.wishlist_adding_toast);
					
					mUserInfo.addWishlist(mMovieInfo.getId(), new BasicAsyncCallback() {
						
						public void onComplete(final boolean[] result, final Object state) {
							
							boolean response = (boolean) result[0];	
							
							if (response == true) {
								runOnUiThread(new Runnable() {public void run() { mWishlistControlWrapper.setVisibility(View.GONE); }});
								toastMessage(R.string.wishlist_added_toast);
							} else {
								toastMessage(R.string.wishlist_adding_error_toast);
							}
				
						}
						
						public void onHttpClientException(final HttpClientException e, final Object state) {
							Log.w("AMM HttpClientException:", e.getMessage());	
						}
			
						public void onIOException(final IOException e, final Object state) {
							Log.w("AMM IOException:", e.getMessage());
						}
			
						public void onWebServiceException(final WebServiceException e, final Object state) {
							Log.w("AMM WebServiceException:", e.getMessage());
							toastMessage(e.getMessage());
						}
			
					}, null);	
				}
				
				break;
			case R.id.playlist_control:
			
				if(mUserInfo != null){
					
					toastMessage(R.string.playlist_adding_toast);
					
					mAmmWebService.getUserTokenBalance(getLoginEmail(), new BasicAsyncCallback() {
						
						public void onComplete(final int[] result, final Object state) {
							
							int tokenBalance = (int) result[0];	
							
							if(tokenBalance > 0){
								
								try {
									
									boolean response = mUserInfo.addPlaylist(mMovieInfo.getId());
									
									if (response == true) {	
										
										runOnUiThread(new Runnable() {public void run() { 
											
											mPlaylistControlWrapper.setVisibility(View.GONE);
											mPlayControlWrapper.setVisibility(View.VISIBLE);
											
											new AlertDialog.Builder(MovieDetailActivity.this)
						                    .setMessage(R.string.playlist_added_toast)
						                    .setPositiveButton(R.string.yes, new DialogInterface.OnClickListener() {
												@Override
												public void onClick(DialogInterface dialog, int which) {
													playVideo(mMovieInfo.getCdnUrl());
												}
											})
						                    .setNegativeButton(R.string.no, null)
						                    .show();
											
										}});
										
									} else {
										toastMessage(R.string.playlist_adding_error_toast);
									}
															
								} catch (HttpClientException e) {
									Log.w("AMM HttpClientException:", e.getMessage());
								} catch (IOException e) {
									Log.w("AMM IOException:", e.getMessage());
								} catch (WebServiceException e) {
									Log.w("AMM WebServiceException:", e.getMessage());
									toastMessage(e.getMessage());
								}
								
							}else{
								toastMessage(R.string.insufficient_token_toast);
							}
				
						}
						
						public void onHttpClientException(final HttpClientException e, final Object state) {
							Log.w("AMM HttpClientException:", e.getMessage());	
						}
			
						public void onIOException(final IOException e, final Object state) {
							Log.w("AMM IOException:", e.getMessage());
						}
			
						public void onWebServiceException(final WebServiceException e, final Object state) {
							Log.w("AMM WebServiceException:", e.getMessage());
							toastMessage(e.getMessage());
						}
			
					}, null);	
					
				}
					
				break;	
			case R.id.rate_movie:
				RateMovieDialogFragment rateMovieDialogFragment = new RateMovieDialogFragment();
			    rateMovieDialogFragment.setRetainInstance(true);
				rateMovieDialogFragment.show(getSupportFragmentManager(), "ratemovie");				
				break;
				
		}
		
	}
    
    private void rateMovie() {
		
		mMovieInfo.rate(getLoginEmail(), mUserRating, new BasicAsyncCallback() {

			public void onComplete(final boolean[] result, final Object state) {

				boolean response = (boolean) result[0];
				
				if (response == true) {
				
					toastMessage(R.string.title_rated_toast);
					
					int ratings = mMovieInfo.getRatings();
					int ratingsCount = mMovieInfo.getRatingsCount();
					
					try {
						ratings = (int) mMovieInfo.getRatingsSync();
						ratingsCount = (int) mMovieInfo.getRatingsCountSync();
					}  catch (HttpClientException e) {
						Log.w("AMM HttpClientException:", e.getMessage());
					} catch (IOException e) {
						Log.w("AMM IOException:", e.getMessage());
					} catch (WebServiceException e) {
						Log.w("AMM WebServiceException:", e.getMessage());
						toastMessage(e.getMessage());
					}
					
					final int currentRatings = ratings;
					final int currentRatingsCount = ratingsCount;
					runOnUiThread(new Runnable() {public void run() {
						mRatings.setImageResource(mRatingsStarOrangeArray[currentRatings]);
						mRatingsCount.setText(NumberFormat.getInstance().format(currentRatingsCount) + " " + getString(R.string.ratings));
					}});
					
				} 
			}

			public void onHttpClientException(final HttpClientException e, final Object state) {
				Log.w("AMM HttpClientException:", e.getMessage());	
			}

			public void onIOException(final IOException e, final Object state) {
				Log.w("AMM IOException:", e.getMessage());
			}

			public void onWebServiceException(final WebServiceException e, final Object state) {
				Log.w("AMM WebServiceException:", e.getMessage());
				toastMessage(e.getMessage());
			}

		}, null);
	}
    
    @SuppressLint("ValidFragment")
	public class RateMovieDialogFragment extends DialogFragment {
        @Override
        public Dialog onCreateDialog(Bundle savedInstanceState) {
            
        	AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
            
            LayoutInflater inflater = getActivity().getLayoutInflater();
            View rateMovieLayout = inflater.inflate(R.layout.rate_movie, null);
            
            final RatingBar ratingBar = (RatingBar) rateMovieLayout.findViewById(R.id.rating_bar);
            ratingBar.setRating((float) mUserRating);
            ratingBar.setOnRatingBarChangeListener(new OnRatingBarChangeListener() {
            	public void onRatingChanged(RatingBar ratingBar, float rating, boolean fromUser) {
					if(rating == 0){
						ratingBar.setRating((float) 1.0);
					}
				}
			});
            
            TextView movieTitle = (TextView) rateMovieLayout.findViewById(R.id.movie_title);
            movieTitle.setText(mMovieInfo.getTitle());
            
            ImageView movieCover = (ImageView) rateMovieLayout.findViewById(R.id.movie_cover);
            mThumbnailImageFetcher.loadImage(mMovieInfo.getCover(), movieCover);
            
            builder.setView(rateMovieLayout)
                   .setPositiveButton(R.string.save, new DialogInterface.OnClickListener() {
                       public void onClick(DialogInterface dialog, int id) {
                    	   if(ratingBar.getRating() > 0){
                    		   mUserRating = (int) ratingBar.getRating();
                    		   mYourRating.setImageResource(mRatingsStarOrangeArray[mUserRating]);
                        	   rateMovie();
                    	   }
                       }
                   })
                   .setNegativeButton(R.string.cancel, new DialogInterface.OnClickListener() {
                       public void onClick(DialogInterface dialog, int id) {
                    	   RateMovieDialogFragment.this.getDialog().cancel();
                       }
                   });
            return builder.create();
        }
    }
	
}
